/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package battleship_server.threads;

import battleship_server.Coordinate;
import battleship_server.Player;
import battleship_server.Manager;
import battleship_server.ServerGameController;
import battleship_server.SocketConnection;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author omar
 */
public class GameLogicThread extends Thread {

    private SocketConnection user1;
    private SocketConnection user2;
    private short[] hundidosuno = new short[5];
    private short[] hundidosdos = new short[5];
    private boolean p1ready = false;
    private boolean p2ready = false;
    private boolean p1win = false;
    private boolean p2win = false;
    public int turn = 0;
    public boolean nextMove = true;

    public GameLogicThread(SocketConnection usOne, SocketConnection usTwo) {
        this.user1 = usOne;
        this.user2 = usTwo;
        player1Array = new Coordinate[10][10];
        player2Array = new Coordinate[10][10];
        inicializator();
    }
    private Coordinate[][] player1Array;
    private Coordinate[][] player2Array;
    private int timeElapsed = 0;
    private int timePlayed = 0;
    private int timeWait = 0;
    private int timeToSet = 0;
    private int gameId = 0;

    private void inicializator() {
        for (int x = 0; x < 10; x++) {
            for (int y = 0; y < 10; y++) {
                player1Array[x][y] = new Coordinate();
                player2Array[x][y] = new Coordinate();
            }
        }
    }

    private boolean someoneWon() {
        boolean v1 = true;
        boolean v2 = true;
        for (int i = 0; i < getHundidosuno().length; i++) {
            if (getHundidosuno()[i] != 2 + i) {
                v1 = false;
            }
        }

        for (int i = 0; i < getHundidosdos().length; i++) {
            if (getHundidosdos()[i] != 2 + i) {
                v2 = false;
            }
        }

        if (v1) {
            p2win = true;
        } else if (v2) {
            p1win = true;
        }

        return v1 || v2;
    }

    public void processMove(int x, int y) {
        try {
            boolean isHit = receivesHit(turn, x, y);
            if (isHit) {
                if (turn == 1) {
                    int ship = player2Array[x][y].getShipType();
                    getHundidosdos()[ship - 2]++;
                    getUsOne().getOut().println("Hit");
                    getUsTwo().getOut().println("Hit");
                    getUsTwo().getOut().println(x);
                    getUsTwo().getOut().println(y);
                } else {
                    int ship = player1Array[x][y].getShipType();
                    getHundidosuno()[ship - 2]++;
                    getUsTwo().getOut().println("Hit");
                    getUsOne().getOut().println("Hit");
                    getUsOne().getOut().println(x);
                    getUsOne().getOut().println(y);
                }
            } else {
                if (turn == 1) {
                    getUsOne().getOut().println("Nope");
                    getUsTwo().getOut().println("Safe");
                    getUsTwo().getOut().println(x);
                    getUsTwo().getOut().println(y);
                } else {
                    getUsTwo().getOut().println("Nope");
                    getUsOne().getOut().println("Safe");
                    getUsOne().getOut().println(x);
                    getUsOne().getOut().println(y);
                }    
            }
            nextMove = true;
        } catch (Exception ex) {
            Logger.getLogger(GameLogicThread.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private boolean receivesHit(int player, int x, int y) {
        return (player == 1 ? player2Array[x][y].receivesHit() : player1Array[x][y].receivesHit());
    }

    public void setShip(int player, int shipType, int startx, int starty, int endx, int endy) {
        if ((startx != endx ? true : false)) {
            for (int i = (startx - 1); i < (endx - 1); i++) {
                if (((player == 1) ? player1Array : player2Array)[i][(starty - 1)].isAvailable()) {
                    ((player == 1) ? player1Array : player2Array)[i][(starty - 1)].placeShip(shipType);
                }
            }
        } else {
            for (int i = (starty - 1); i < (endy - 1); i++) {
                if (((player == 1) ? player1Array : player2Array)[(startx - 1)][i].isAvailable()) {
                    ((player == 1) ? player1Array : player2Array)[i][(starty - 1)].placeShip(shipType);
                }
            }
        }

        if (shipType > 5) {
            if (player == 1) {
                p1ready = true;
            } else {
                p2ready = true;
            }
        }

    }

    @Override
    public void run() {
        user1.gameLogicThread = this;
        user2.gameLogicThread = this;

        //Selección de barcos...
        new SetShipsThread(1, this, user1).start();
        new SetShipsThread(2, this, user2).start();

        while (!(p1ready && p2ready)) {
        }

        user1.getOut().println("GAME-READY");
        user2.getOut().println("GAME-READY");

        boolean turno = new Random().nextBoolean();
        while (!someoneWon()) {
            try {
                if (turno && nextMove) {
                    getUsOne().getOut().println("Your turn.");
                    getUsTwo().getOut().println("Wait");
                    nextMove = false;
                    turn = 1;
                    turno = !turno;
                } else if (nextMove) {
                    getUsTwo().getOut().println("Your turn.");
                    getUsOne().getOut().println("Wait");
                    nextMove = false;
                    turn = 2;
                    turno = !turno;
                }
                Thread.sleep(200);
            } catch (InterruptedException ex) {
                Logger.getLogger(GameLogicThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        short winP = (short) (p1win ? 1 : 2);

        ServerGameController.getInstance().database.updateScores((winP == 1 ? getUsOne().getPlayer().getUser(): getUsTwo().getPlayer().getUser()), 
                (winP == 1 ? getUsTwo().getPlayer().getUser(): getUsOne().getPlayer().getUser()));
        if (winP == 1){
            getUsOne().getOut().println("You won");
            getUsTwo().getOut().println("You lost");
        } else {
            getUsTwo().getOut().println("You won");
            getUsOne().getOut().println("You lost");
        }
        Manager.games.remove(this);
    }

    /**
     * @return the usuno
     */
    public SocketConnection getUsOne() {
        return user1;
    }

    /**
     * @return the usdos
     */
    public SocketConnection getUsTwo() {
        return user2;
    }

    /**
     * @return the hundidosuno
     */
    public short[] getHundidosuno() {
        return hundidosuno;
    }

    /**
     * @return the hundidosdos
     */
    public short[] getHundidosdos() {
        return hundidosdos;
    }
}
